# ============================================================
# * Copyright © hk. 2022-2025. All rights reserved.
# * File name: CMakeLists.txt
# * Author   : 苏木
# * Date     : 2025-05-22
# * Version  : 
# * Description: cmake version 3.16.3
# ============================================================
## https://cmake.com.cn/cmake/help/latest/guide/tutorial/index.html
## https://cmake.org/cmake/help/latest/

# 指定 CMake 的最低版本要求
# --------------------------------------------------
cmake_minimum_required(VERSION 3.10)


# 设置项目名称和使用的编程语言
# --------------------------------------------------
project(SPROJECT C)


# 指定可执行程序和源文件
# --------------------------------------------------
add_executable(app_demo.out main.c)

# Macro和function的区别
# --------------------------------------------------

# 2. 区别2：
#         函数内可以使用return，函数会产生新的作用域，在函数中return只意味着退出函数作用域，父作用域的代码语句会正常执行。
#         宏中不建议使用return，宏只是等价替换，当调用宏时，相当于把宏中命令语句替换到相应的位置，所以在宏中执行return命令之后，整个CMake进程会退出执行，不再继续执行其他语句。

# 变量访问：函数只能访问自己的局部变量；宏可以访问和修改调用者的变量
message(STATUS "==> ${CMAKE_VERSION} 演示2: return")
# 定义函数
function(test_func_argument arg)
	message(STATUS "[函数] 收到参数: ${arg}, ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
    message(STATUS "	  ARGV0: ${ARGV0}") # 打印ARGV0参数值
    
    # 打印参数个数
    list(LENGTH ARGV argv_len)
    message(STATUS "	  length of ARGV: ${argv_len}")
    
    if (argv_len GREATER 3)
        foreach (loop_var IN LISTS ARGV) # ARGV is a true variable
            message(STATUS "	  loop_var: ${loop_var}")
        endforeach()
    else()
        message(STATUS "	  in func exec return")
        return()  ## 从此退出
    endif()
    message(STATUS "	  after return")
endfunction()

# 定义宏
macro(test_macro_argument arg)
	message(STATUS "[宏] 收到参数: ${arg}, ARGC: ${ARGC}, ARGV: ${ARGV}, ARGN: ${ARGN}")
    message(STATUS "	 ARGV0: ${ARGV0}") # 打印ARGV0参数值
    
    # 定义一个变量，因为宏是没有这个ARGV参数
    set(list_var "${ARGV}")
    
    # 打印参数个数
    list(LENGTH list_var argv_len)
    message(STATUS "	 length of ARGV: ${argv_len}")
 
    if (argv_len GREATER 3)
        foreach (loop_var IN LISTS list_var) # list_var is a true variable
            message(STATUS "	 loop_var: ${loop_var}")
        endforeach()
    else()
        message(STATUS "	 in macro exec return")
        return()  ## 从此退出
    endif()
    message(STATUS "	 after return")
endmacro()

test_func_argument(22 44 66 88 100)
message(STATUS "\n")
 
test_func_argument(10 11 12)
message(STATUS "\n")

test_macro_argument(11 33 55 77 99)
message(STATUS "\n")
message(STATUS "after exec macro with 5 value to continue\n")

test_macro_argument(20 21 22)
message(STATUS "\n")
message(STATUS "after exec macro with 3 value to continue")

message("")

# 输出如下：
# -- ==> 3.16.3 演示2: return
# -- [函数] 收到参数: 22, ARGC: 5, ARGV: 22;44;66;88;100, ARGN: 44;66;88;100
# --        ARGV0: 22
# --        length of ARGV: 5
# --        loop_var: 22
# --        loop_var: 44
# --        loop_var: 66
# --        loop_var: 88
# --        loop_var: 100
# --        after return
# -- 

# -- [函数] 收到参数: 10, ARGC: 3, ARGV: 10;11;12, ARGN: 11;12
# --        ARGV0: 10
# --        length of ARGV: 3
# --        in func exec return
# -- 

# -- [宏] 收到参数: 11, ARGC: 5, ARGV: 11;33;55;77;99, ARGN: 33;55;77;99
# --       ARGV0: 11
# --       length of ARGV: 5
# --       loop_var: 11
# --       loop_var: 33
# --       loop_var: 55
# --       loop_var: 77
# --       loop_var: 99
# --       after return
# -- 

# -- after exec macro with 5 value to continue

# -- [宏] 收到参数: 20, ARGC: 3, ARGV: 20;21;22, ARGN: 21;22
# --       ARGV0: 20
# --       length of ARGV: 3
# --       in macro exec return